How To: Manually transfer user scripts from Greasemonkey to Scriptish
Until a better solution is created, you will have to manually transfer your user scripts from Greasemonkey to Scriptish.
-
Find your profile folder. You should see a folder named
gm_scripts
, containing all the user scripts installed that you had installed for Greasemonkey. - If you have already installed Scriptish you'll also see a folder named
scriptish_scripts
. It's created automatically when you install Scriptish, containing two files (scriptish-blocklist.json & scriptish-config.json) a few bytes each. Delete thescriptish-config.json
file and then copy the contents of thegm_scripts
folder into thescriptish_scripts
folder. - Otherwise (if there isn't a
scriptish_scripts
folder already), create a copy of thegm_scripts
folder and call itscriptish_scripts
, or, if you no longer wish to use Greasemonkey, simply rename thegm_scripts
folder.
In any case, it is strongly recommended that you uninstall Greasemonkey and close Firefox before renaming the folder.
Also, it's crucial that you delete the scriptish-config.json
(if it exists)
in order to be recreated for the added scripts the next time you launch Firefox,
otherwise the User Scripts list tab will appear empty.
This step is the really painful part, especially for some scripts, so if you can live with your settings being reset skip these instructions.
- Go to about:config and put
greasemonkey.scriptvals
into the filter bar - Copy each entry's Name, Value, and Type to a text file
- For each name, replace
greasemonkey.scriptvals
withextensions.scriptish.scriptvals
- Right-click in the about:config window and create a new String, Integer, or Boolean with the modified Name and Value pair
Also you can open prefs.js
with your favorite plain-text editor and do step 3.
Namespace separator is @
in scriptish and /
in greasemonkey, thats why you need to replace it too.
Here's a python 3 program to automate the conversion, put prefs.js and scriptish-config.json in the same directory as the script
#by smk
import json
import re
from bisect import bisect_left
def anyStartsWith(word_fragment,wordlist):
'''
assumes that wordlist is sorted
'''
try:
closest=wordlist[bisect_left(wordlist, word_fragment)-1]
if word_fragment.startswith(closest):
return closest
except IndexError:
#word_fragment is greater than all entries in wordlist
return None
class KeyConverter:
def __init__(self):
self.gmScriptInfos=self.getGMScriptInfos()
self.gmAddonId='extensions.greasemonkey.scriptvals'
self.scriptishAddonId='extensions.scriptish.scriptvals'
def getGMScriptInfos(self):
'''
returns:
{scriptId: (namespace,name)}
'''
scriptInfos={}
scriptishConfig=json.load(open('scriptish-config.json','r'))
for script in scriptishConfig['scripts']:
namespace=script['namespace']
name=script['name']
scriptInfos[namespace+'/'+name]=(namespace,name)
#make sure there are no namespace ambiguity, by checking if one namespace can be the substring of another
#using pairs as an algorithm is incorrect, consider ['a','ab','ac']
startsWithList=scriptInfos.keys()
for scriptId in startsWithList:
curStartsWithList=set(startsWithList)
curStartsWithList.remove(scriptId)
curStartsWithList=sorted(curStartsWithList)
closest=anyStartsWith(scriptId,curStartsWithList)
if closest is not None:
raise Exception('scriptId {!r} starts with scriptId {!r}'.format(scriptId,closest))
return scriptInfos
def convertKey(self,key):
fragment=key[len(self.gmAddonId)+1:]
#greasemonkey allows '.', and '/' in GM_setValue, and also allows them in the namespace & script names, so there is no way to no where the namespace ends
# without getting the script ids
startsWithList=sorted(self.gmScriptInfos.keys())
scriptId=anyStartsWith(fragment,startsWithList)
if scriptId is None:
raise ValueError('script with key {!r} does\'nt exist'.format(key))
scriptKey=fragment[len(scriptId)+1:]
namespace,name=self.gmScriptInfos[scriptId]
#remove special chars from namespace, see extensions/modules/script/script.js > nonIdChars
nonIdChars=r'[^\w@\.\-_]+'
namespace=re.sub(nonIdChars,'',namespace)
name=re.sub(nonIdChars,'',name)
scriptId='@'.join((name,namespace))
return '.'.join([self.scriptishAddonId,scriptId,scriptKey])
def main():
keyConverter=KeyConverter()
sr=open('prefs.js','rb')
outSr=open('prefs.out.js','wb')
for line in sr.readlines():
line=line.decode()
if not line.startswith('user_pref('):
outSr.write(line.encode())
else:
startIndex=len('user_pref(')
endIndex=line.rindex(');')
key,value=json.loads('['+line[startIndex:endIndex]+']')
if key.startswith(keyConverter.gmAddonId+'.'):
try:
key=keyConverter.convertKey(key)
except ValueError as e:
print(e)
line=json.dumps([key,value])[1:-1]
outSr.write(('user_pref('+line+');\r\n').encode())
if __name__=='__main__':
main()
Another way to is to create a symlink to the folder gm_scripts
, and call it scriptish_scripts
(or visa versa). Using this method, you will store all of your scripts, their resources, and settings in one folder, where they will be shared by Scriptish and Greasemonkey.